package com.wang.proxydemo.jdkProxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 代理工具类 ProxyUtil
 * 作用: 为对象创建代理
 */
public class ProxyUtil {
    /**
     * 给Animal对象创建代理
     * @param animal 被代理的明星对象
     * @return 代理对象
     */
    public static IAnimal createProxy(Animal animal) {
        return (IAnimal) Proxy.newProxyInstance(
                ProxyUtil.class.getClassLoader(),   // 参数一: 用于指定用哪个类加载器去加载生成的代理类
                new Class[]{IAnimal.class},         // 参数二: 用于指定代理对象要实现哪些接口
                new InvocationHandler() {           // 参数三: 用于指定代理对象要干什么事情
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        /*
                        参数1: 要代理的对象
                        参数2: 要运行的方法
                        参数3: 方法的参数
                         */
                        // 前置处理
                        if (("eat").equals(method.getName())) {
                            System.out.println("饲养员准备食物");
                        } else if ("sleep".equals(method.getName())) {
                            System.out.println("饲养员准备草席");
                        }

                        // 调用目标类的原始方法 (通过代理调用父类方法)
                        Object result = (method.invoke(animal, args));

                        // 后置处理
                        if (("eat").equals(method.getName())) {
                            System.out.println("饲养员收拾剩余食物");
                        } else if ("sleep".equals(method.getName())) {
                            System.out.println("饲养员叫醒小动物");
                        }

                        return result;
                    }
                });
    }
}
/* java.lang.reflect.Proxy 类: 提供了为对象生成代理对象的方法

public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
参数一：用于 指定用哪个类加载器 去加载生成的代理类
参数二：指定接口. 这些接口用于指定生成的代理长什么样子, 也就是有哪些方法
参数三：用来指定生成的代理对象要干什么事情
*/
